// //验证前后台进程
// #include<iostream>

// using std::cin;
// using std::cout;
// using std::endl;


// int main()
// {
//     while(1)
//         cout << "hello proc!" << endl;

//     return 0;
// }


// //1.键盘产生信号
// #include<iostream>
// #include<signal.h>
// #include<unistd.h>
// #include<sys/types.h>

// using std::cin;
// using std::cout;
// using std::endl;


// void handler(int signo)
// {
//     cout << "我是一个进程, 刚刚获取了一个信号: " << signo << endl;
// }

// int main()
// {
//     //这里不是调用handler方法, 只是设置一个回调, 让SIGINT(2)产生的时候, 该方法才会被调用
//     //如果不产生SIGINT(2), 该方法不会被调用
//     //ctr+c本质上是给前台进程发送2号信号给目标进程, 目标进程默认对2号信号的处理是终止自己
//     //今天我们更改了对2号信号的处理, 设置了用户自定义处理方法 
//     signal(SIGINT, handler);//注册
//     sleep(3);
//     cout << "进程已经设置完了" << endl;
//     sleep(3);
//     while(true)
//     {
//         cout << "我是一个正在运行的进程: " << getpid() << endl;
//         sleep(1);
//     }

//     return 0;
// }



//2.系统接口完成
//我想要写一个 kill 命令, 模拟实现
// #include<iostream>
// #include<string>
// #include<cstdlib>
// #include<sys/types.h>
// #include<signal.h>
// #include<cstring>
// #include<cerrno>

// using std::cin;
// using std::cout;
// using std::cerr;
// using std::endl;


// void handler(int signo)
// {
//     cout << "我是一个进程, 刚刚获取了一个信号: " << signo << endl;
// }

// static void Usage(const std::string& proc)
// {
//     cout << "Usage:\n\t" << proc << " signo pid" << endl;
// }

// int main(int argc, char* argv[])
// {
//     if(argc != 3)
//     {
//         Usage(argv[0]);
//         exit(1);
//     }
//     if(kill(static_cast<pid_t>(atoi(argv[2])), atoi(argv[1])) == -1)
//     {
//         cerr << "kill:" << strerror(errno) << endl;
//         exit(2);
//     }

//     return 0;
// }

// #include<iostream>

// using std::cin;
// using std::cout;
// using std::endl;


// int main()
// {
//     while(1)
//         cout << "hello mykill!" << endl;

//     return 0;
// }


// #include<iostream>
// #include<unistd.h>
// #include<sys/types.h>
// #include<signal.h>

// using std::cin;
// using std::cout;
// using std::endl;


// int main()
// {
//     // //kill():向任意进程发送任意信号
//     // kill(getpid(), 9);

//     // //raise():给自己发送任意信号
//     // raise(9);

//     //abort():给自己发送SIGABRT信号
//     abort();

//     while(1)
//         cout << "hello proc!" << endl;

//     return 0;
// }


// #include<iostream>
// #include<unistd.h>
// #include<sys/types.h>
// #include<signal.h>

// using std::cin;
// using std::cout;
// using std::cerr;
// using std::endl;

// void handler(int signo)
// {
//     cout << "我是一个进程, 刚刚获取了一个信号: " << signo << endl;
// }

// static void showPending(sigset_t* pendings)
// {
//     for(int sig = 0; sig <= 31; sig++)
//     {
//         if(sigismember(pendings, sig))
//         {
//             cout << "1";
//         }
//         else
//         {
//             cout << "0";
//         }
//     }
//     cout << endl;
// }

// int main(int argc, char* argv[])
// {
//     cout << "pid: " << getpid() << endl;

//     //屏蔽某信号
//     sigset_t bsig, obsig;
//     sigemptyset(&bsig);
//     sigemptyset(&obsig);

//     for(int sig = 1; sig <= 31; sig++)
//     {
//         //添加某信号到信号屏蔽字中
//         sigaddset(&bsig, sig);
//         signal(sig, handler);
//     }

//     //设置用户级的信号屏蔽字到内核中, 让当前进程屏蔽某信号
//     sigprocmask(SIG_SETMASK, &bsig, &obsig);

//     //不断的获取当前进程的pending信号集
//     sigset_t pendings;
//     int cnt = 0;
//     while(true)
//     {
//         //清空信号集
//         sigemptyset(&pendings);

//         //获取当前进程的pending信号集
//         if(sigpending(&pendings) == 0)
//         {
//             //打印一下当前进程的pending信号集
//             showPending(&pendings);
//         }
//         sleep(1);
//         cnt++;
//         if(cnt == 20)
//         {
//             cout << "解除对所有信号的block..." << endl;
//             sigset_t sigs;
//             sigemptyset(&sigs);
//             sigaddset(&sigs, 2);
//             sigprocmask(SIG_UNBLOCK, &sigs, nullptr);
//         }
//     }


//     return 0;
// }


// #include<iostream>
// #include<signal.h>
// using std::cin;
// using std::cout;
// using std::endl;

// int flag = 0;

// void handler(int sig)
// {
//     cout << "flag 0 -> 1" << endl;
//     flag = 1;
// }

// int main()
// {
//     signal(2, handler);
//     while(!flag);
//     cout << "进程正常退出" << endl;

//     return 0;
// }


// #include<iostream>
// #include<signal.h>
// using std::cin;
// using std::cout;
// using std::endl;

// volatile int flag = 0;

// void handler(int sig)
// {
//     cout << "flag 0 -> 1" << endl;
//     flag = 1;
// }

// int main()
// {
//     signal(2, handler);
//     while(!flag);
//     cout << "进程正常退出" << endl;

//     return 0;
// }


// #include<iostream>
// #include<signal.h>
// #include<unistd.h>
// using std::cin;
// using std::cout;
// using std::endl;

// void handler(int signo)
// {
//     cout << "我是一个进程, 刚刚获取了一个信号: " << signo << endl;
// }


// int main()
// {
//     signal(2, handler);//捕捉处理,自定义2号信号
//     signal(3, handler);//捕捉处理,自定义3号信号

//     sleep(3);
//     cout << "进程已经设置完了" << endl;
//     sleep(3);
//     while(true)
//     {
//         cout << "我是一个正在运行的进程: " << getpid() << endl;
//         sleep(1);
//     }

//     return 0;
// }


// #include<iostream>
// #include<string>
// #include<cstring>
// #include<cerrno>
// #include<cstdlib>
// #include<signal.h>
// #include<sys/types.h>
// #include<unistd.h>
// using std::cin;
// using std::cout;
// using std::cerr;
// using std::endl;

// void handler(int signo)
// {
//     cout << "我是一个进程, 刚刚获取了一个信号: " << signo << endl;
// }

// static void Usage(const std::string& proc)
// {
//     cerr << "Usage:\n\t" << proc << " signo pid" << endl;
// }

// int main(int argc, char* argv[])
// {
//     if(argc != 3)
//     {
//         Usage(argv[0]);
//         exit(1);
//     }
//     if(kill(static_cast<pid_t>(atoi(argv[2])), atoi(argv[1])) == -1)
//     {
//         cerr << "kill: " << strerror(errno) << endl;
//         exit(2);
//     }


//     return 0;
// }


// #include<iostream>
// #include<string>
// #include<cstring>
// #include<cerrno>
// #include<cstdlib>
// #include<signal.h>
// #include<sys/types.h>
// #include<unistd.h>
// using std::cin;
// using std::cout;
// using std::cerr;
// using std::endl;

// void handler(int signo)
// {
//     cout << "我是一个进程, 刚刚获取了一个信号: " << signo << endl;
// }

// static void showPending(sigset_t* pendings)
// {
//     for(int sig = 1; sig <= 31; sig++)
//     {
//         if(sigismember(pendings, sig))
//             cout << "1";
//         else
//             cout << "0";
//     }
//     cout << endl;
// }

// int main(int argc, char* argv[])
// {
//     cout << "pid: " << getpid() << endl;

//     //屏蔽某信号
//     sigset_t bsig, obsig;
//     sigemptyset(&bsig);
//     sigemptyset(&obsig);

//     for(int sig = 1; sig <= 31; sig++)
//     {
//         //添加某信号到信号集中
//         sigaddset(&bsig, sig);
//         signal(sig, handler);
//     }

//     //设置用户级的信号屏蔽字到内核中, 让当前进程屏蔽某信号
//     sigprocmask(SIG_SETMASK, &bsig, &obsig);

//     //不断地获取当前进程的pending信号集
//     sigset_t pendings;
//     int cnt = 0;
//     while(true)
//     {
//         //清空信号集
//         sigemptyset(&pendings);

//         //获取当前进程的pending信号集
//         if(sigpending(&pendings) == 0)
//         {
//             //打印一下当前进程的pending信号集
//             showPending(&pendings);
//         }
//         sleep(1);
//         cnt++;
//         if(cnt == 20)
//         {
//             cout << "解除对所有信号的block..." << endl;
//             sigset_t sigs;
//             sigemptyset(&sigs);
//             sigaddset(&sigs, 2);
//             sigprocmask(SIG_UNBLOCK, &sigs, nullptr);
//         }

//     }

//     return 0;
// }




// #include<iostream>
// #include<string>
// #include<cstring>
// #include<cassert>
// #include<cerrno>
// #include<cstdlib>
// #include<signal.h>
// #include<sys/types.h>
// #include<sys/wait.h>
// #include<unistd.h>
// using std::cin;
// using std::cout;
// using std::cerr;
// using std::endl;

// void FreeChld(int signo)
// {
//     assert(signo == SIGCHLD);

//     while(true)
//     {
//         pid_t id = waitpid(-1, nullptr, WNOHANG);


//     }
// }   

// int main()
// {
//     signal(SIGCHLD, FreeChld);

//     return 0;
// }
